<?php
/** 
 * 
 *
 * @package api
 * @subpackage db
 * @author Richard Fullmer <php-api@byu.edu>
 * 
 * @version 1.0
 */
/**
 * 
 */
require_once( "lang/Comparable.php" );
require_once( "db/AbstractDatabaseObject.php" );
require_once( "lang/Object.php" );
require_once( "lang/ClassCastException.php" );

/**
 * @package api
 * @subpackage db
 */
 
/*
abstract class DatabaseObject extends Object implements Comparable, Mappable {
	private $id;
	
	public function __construct( $id = null ) {
		$this->id = $id;
		if (! $this->id) {
			$this->id = $this->mapper()->newId();
			$this->markClean();
		}
	}
	
	public function setId( $id ) {
		$this->id = $id;
		$this->markDirty();
	}
	
	public function getId() {
		return $this->id;
	}
	
	// Ensures that if we return null for null values
	protected function ensure($expr, $return_value) {
		if ($expr) return $return_value;
		else return null;
	}
	
	public function compareTo( Object $o ) {
		if ($this->getClass() != $o->getClass())
			throw new ClassCastException();
			
		if ($this->getId() == $o->getId())
			return 0;
		elseif ($this->getId() > $o->getId())
			return -1;
		elseif ($this->getId() < $o->getId())
			return 1;
	}
	
	public function equals( Object $o ) {
		if ($this->getClass() != $o->getClass())
			throw new ClassCastException();
			
		return ( $this->getId() == $o->getId() );
	}
	
	
	function __clone() {
        $this->id = null;
    }
	
	public function markNew() {
	
	}
	public function markDirty() {
	
	}
	public function markClean() {
	
	}
	public function markDeleted() {
	
	}	
	
	public function mapper() { }
	
	public static function getMapper( $type ) { }
}
*/


class DatabaseObject extends AbstractDatabaseObject {
	private $id;
	private $table;
	private $fields = array();
	
	private $new = false;
	private $delete = false;
	private $dirty = false;
	
	public function __construct( $dsn, $table, $fields ) {
		parent::__construct( $dsn );
		
		$this->table = $table;
		foreach( $fields as $key )
			$this->fields[ $key ] = null;
			
		$this->new = true;
  	}

	public function getTableName() {
		return $this->table;
	}

  	public function __call( $method, $args ) {
		if ( preg_match( "/set(.*)/", $method, $found ) ) {
			if ( array_key_exists( $found[1], $this->fields ) ) {
				$this->fields[ $found[1] ] = $args[0];
				$this->dirty = true;
				return true;
			}
		}
		else if ( preg_match( "/get(.*)/", $method, $found ) ) {
			if ( array_key_exists( $found[1], $this->fields ) ) {
				return $this->fields[ $found[1] ];
			}
		}
		return false;
	}
	
	public function load( $id ) {
	
		$res = $this->doQuery( "SELECT * FROM ".$this->table." WHERE id=?", array( $id ) );
		
		$res->fetchInto( $row, DB_FETCHMODE_ASSOC );
		$this->id = $id;
		foreach( array_keys( $row ) as $key )
			$this->fields[ $key ] = $row[ $key ];
			
		$this->new = true;
	}
	
	private function insert() {
		
		$fields = "id, ";
		$fields .= join( ", ", array_keys( $this->fields ) );
		
		$this->id = $this->getNextId();
		$inspoints = array( $this->id );
		foreach( array_keys( $this->fields ) as $field )
			$inspoints []= "?";
		$inspt = join( ", ", $inspoints );
		
		$sql = "INSERT INTO ".$this->table." ( $fields ) VALUES ( $inspt )";
		
		$values = array();
		foreach( array_keys( $this->fields ) as $field )
			$values []= $this->fields[ $field ];
		
		$sth = $this->prepareStatement( $sql );
		$this->doExecute( $sth, $values );
		
		$this->new = false;
		$this->dirty = false;
		
		return $this->id;
	}
	
	private function update() {
		if ($this->dirty) {
			$sets = array();
			$values = array();
			foreach( array_keys( $this->fields ) as $field ) {
				$sets []= $field.'=?';
				$values []= $this->fields[ $field ];
			}
			$set = join( ", ", $sets );
			$values []= $this->id;
			
			$sql = 'UPDATE '.$this->table.' SET '.$set. ' WHERE '.$this->table.'_id=?';
			
			$sth = $this->prepareStatement( $sql );
			$this->doExecute( $sth, $values );
			
			$this->dirty = false;
		}
	}
	
	public function delete() {
	
		$sth = $this->db->prepare( 'DELETE FROM '.$this->table.' WHERE '. $this->table.'_id=?' );
		$sth->execute( array( $this->id ) );
	}
	
	public function delete_all() {
	
		$sth = $this->db->prepare( 'DELETE FROM '.$this->table );
		$sth->execute();
	}
	
	public function __destruct() {
		if ( $this->new )	
			$this->insert();
		elseif ( $this->dirty )
			$this->update();
	}
	
}
	

?>